
package edu.yonsei.iwb.sdt.datastructure.tree;

import edu.yonsei.iwb.sdt.datastructure.rule.DecisionRule;
import com.hp.hpl.jena.rdf.model.Resource;
import java.util.Enumeration;
import java.util.Vector;
import edu.yonsei.iwb.sdt.SDTLearner;
import edu.yonsei.iwb.sdt.datastructure.TargetInstance;
import edu.yonsei.iwb.sdt.datastructure.TargetInstanceSet;
import edu.yonsei.iwb.sdt.datastructure.TargetInstanceValueInformation;
import edu.yonsei.iwb.sdt.util.UtilFunctions;
import java.util.ArrayList;

/**
 *
 * @author JDK
 */
public class DNode {
    private Vector<TargetInstance> instanceSet = new Vector();
    private Vector<DEdge> edgeSet = new Vector<DEdge>();
    private double entropy;
    private DecisionRule rc;
//    private TrueFalseInformation tfi;
    
    private int finalClassLabel;
    
    private TargetInstanceValueInformation tivi;
    
    private String refinement_name;
    public int NODE_TYPE;
    public int NODE_ID;
    
    public DNode(){
        
    }
    
    public DNode(Vector<TargetInstance> instanceSet, String refname){
        this.instanceSet = instanceSet;
        this.refinement_name = refname;
//        System.out.println("+++++++++++++++++++++++++++++++++");
//        UtilFunctions.printVectorOfResource(this.instanceSet);
        this.NODE_ID = SDTLearner.NODE_ID++;
    }
    
    public DNode(Vector<TargetInstance> instanceSet, String refname, int nodeid, double en){
        this.instanceSet = instanceSet;
        this.refinement_name = refname;
        this.entropy = en;
        this.NODE_ID = nodeid;
    }
    
    public DNode(String refname, int nodeid, double en){
//        this.instanceSet = instanceSet;
        this.refinement_name = refname;
        this.entropy = en;
        this.NODE_ID = nodeid;
    }
        
    public String getRefinementName(){
        return this.refinement_name;
    }
    
    public void setEdge(DEdge edge){
        this.edgeSet.add(edge);
    }
    
    public Vector<DEdge> getEdge(){
        return this.edgeSet;
    }    
    
    public void setFinalClassLabel(int value){
        this.finalClassLabel = value;
    }
    
    public void setFinalClassLabel(){
        int highest = 0;        
//        Hashtable<Integer, Vector<TargetInstance>>
        Enumeration<Integer> keys = this.tivi.keys();
        while(keys.hasMoreElements()){
            int cl = keys.nextElement();            
            Vector<TargetInstance> tiset = this.tivi.get(cl);
            int size = tiset.size();
            if(size > highest){
                highest = size;
                this.finalClassLabel = cl;
            }            
        }        
    }
    
    public int getFinalClassLabel(){
        return this.finalClassLabel;
    }
    
    /**
     * value를 키로 하는 인스턴스셋 정의
     * @param tis 
     */
    public void setTargetValueInstanceInformation(TargetInstanceSet tis){
        this.tivi = new TargetInstanceValueInformation();
        for (int i = 0; i < this.instanceSet.size(); i++) {
            TargetInstance ti = this.instanceSet.get(i);
            this.tivi.putTargetInstaceValue(ti, tis.get(ti));
        }
    }
    
    public void setTargetValueInstanceInformation(){
        this.tivi = new TargetInstanceValueInformation();
        for (int i = 0; i < this.instanceSet.size(); i++) {
            TargetInstance ti = this.instanceSet.get(i);
            this.tivi.putTargetInstaceValue(ti, ti.getTargetvalue());
        }
    }
    
    public TargetInstanceValueInformation getTargetInstanceValueInformation(){
        return this.tivi;
    }
    
//    public void setRuleComposer(Refinement ref){
//        this.rc = new RuleComposer(ref);
//    }
//    
//    public void setRuleComposer(NodeExpressionRule oldrc, Refinement ref){
//        this.rc = new NodeExpressionRule(oldrc, ref);
//    }
    
    public DecisionRule getRuleComposer(){
        return this.rc;
    }
    
//    public String getRuleSentence(){
//        return this.rc.getRuleString();
//    }
    
    
//    public void setTrueFalseInformation(TargetInstanceSet tis){
//        this.tfi = new TrueFalseInformation();
////        System.out.println("++++++++++    " + this.instanceSet.size());
//        for (int i = 0; i < this.instanceSet.size(); i++) {
//            Resource r = this.instanceSet.get(i);
//            if(tis.get(r)){
//                this.tfi.addTrueInstance(r);
//            }else{
//                this.tfi.addFalseInstance(r);
//            }
//        }
//    }
    
//    public TrueFalseInformation getTrueFalseInformation(){
//        return this.tfi;
//    }
    
    public Vector<TargetInstance> getInstanceSet(){
        return this.instanceSet;
    }
    
    public int getInstanceSetSize(){
        return this.instanceSet.size();
    }
    
    public void setEntropy(){
//        this.entropy = UtilFunctions.calculateEntropy(this.tfi);
//        System.out.println("----**** " + this.refinement_name);
//        System.out.println(this.tivi.toString());
        this.entropy = UtilFunctions.calculateEntropy(this.tivi, this.instanceSet.size());
        
    }    
    
    public double getEntropy(){
        return this.entropy;
    }
    
    
    @Override
    public String toString(){
        String s = new String();
        s = "Node ID : " + this.NODE_ID +"\n";
        
        Enumeration<Integer> keye = tivi.keys();        
        while(keye.hasMoreElements()){            
            int key = keye.nextElement();
            Vector<TargetInstance> rset = tivi.get(key);
            int valueInsnum = rset.size();
            s += "Class " +key+ " : "+ valueInsnum + " / ";     
        }        
        
        s += "\nEntropy : " + this.entropy + "\n";
        return s;
    }
    
    public String toGUIString(){
        String s = new String();
        s = "Node ID : " + this.NODE_ID +"<br>";
        
        Enumeration<Integer> keye = tivi.keys();        
        while(keye.hasMoreElements()){            
            int key = keye.nextElement();
            Vector<TargetInstance> rset = tivi.get(key);
            int valueInsnum = rset.size();
            s += "Class " +key+ " : "+ valueInsnum + " ";     
        }
        
        s += "<br>Entropy : " + this.entropy + "<br>";
        return s;
    }
    
    public String getTooltipTEXT(){
//        String s = new String();        
        
//        for (int i = 0; i < this.tfi.getTrueInstanceSet().size(); i++) {
//            Resource r = this.tfi.getTrueInstanceSet().get(i);
//            
//            s = s + r.toString() + "<br>";            
//            
//        }
//        if(!this.tfi.getTrueInstanceSet().isEmpty()){
//            s = "<b>Positive Instance : </b><br>" + s + "<br>";
//        }
//        
//        if(!this.tfi.getFalseInstanceSet().isEmpty()){
//            s = s + "<b>Negative Instance : </b><br>";
//        }        
////        s += "<b>Negative Instance : </b><br>";
//        for (int i = 0; i < this.tfi.getFalseInstanceSet().size(); i++) {
//            Resource r = this.tfi.getFalseInstanceSet().get(i);            
//            s = s + r.toString() + "<br>";            
//            
//        }
//        
//        s = "<html><center>" + s + "</center></html>";
        
//        return s;
        return this.tivi.getResourceListByClassValueString();
    }
}
